import React, { useMemo } from 'react';

import { FlowNodeInputTypeEnum } from '@/types/workflow/constant';
import { FlowNodeInputItemType } from '@/types/workflow/io';

import InputLabel from './Label';

// 直接导入组件而不是懒加载
import DynamicInputs from './templates/DynamicInputs/index';
import JsonEditor from './templates/JsonEditor';
import NumberInput from './templates/NumberInput';
import Reference from './templates/Reference';
import Select from './templates/Select';
import SelectApp from './templates/SelectApp';
import SelectDataset from './templates/SelectDataset';
import SelectDatasetParams from './templates/SelectDatasetParams';
import SelectLLMModel from './templates/SelectLLMModel';
import SettingLLMModel from './templates/SettingLLMModel';
import SettingQuotePrompt from './templates/SettingQuotePrompt';
import Switch from './templates/Switch';
import Textarea from './templates/Textarea';
import TextInput from './templates/TextInput';
import { RenderInputProps } from './type';

const RenderList: {
  types: FlowNodeInputTypeEnum[];
  Component: React.ComponentType<RenderInputProps>;
}[] = [
  {
    types: [FlowNodeInputTypeEnum.reference],
    Component: Reference,
  },
  {
    types: [FlowNodeInputTypeEnum.select],
    Component: Select,
  },
  {
    types: [FlowNodeInputTypeEnum.numberInput],
    Component: NumberInput,
  },
  {
    types: [FlowNodeInputTypeEnum.switch],
    Component: Switch,
  },
  {
    types: [FlowNodeInputTypeEnum.selectApp],
    Component: SelectApp,
  },
  {
    types: [FlowNodeInputTypeEnum.selectLLMModel],
    Component: SelectLLMModel,
  },
  {
    types: [FlowNodeInputTypeEnum.settingLLMModel],
    Component: SettingLLMModel,
  },
  {
    types: [FlowNodeInputTypeEnum.selectDataset],
    Component: SelectDataset,
  },
  {
    types: [FlowNodeInputTypeEnum.selectDatasetParamsModal],
    Component: SelectDatasetParams,
  },
  {
    types: [FlowNodeInputTypeEnum.addInputParam],
    Component: DynamicInputs,
  },
  {
    types: [FlowNodeInputTypeEnum.JSONEditor],
    Component: JsonEditor,
  },
  {
    types: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt],
    Component: SettingQuotePrompt,
  },
  {
    types: [FlowNodeInputTypeEnum.input],
    Component: TextInput,
  },
  {
    types: [FlowNodeInputTypeEnum.textarea],
    Component: Textarea,
  },
];

const hideLabelTypeList = [FlowNodeInputTypeEnum.addInputParam, FlowNodeInputTypeEnum.switch];

type Props = {
  flowInputList: FlowNodeInputItemType[];
  nodeId: string;
  CustomComponent?: Record<string, (e: FlowNodeInputItemType) => React.ReactNode>;
  mb?: number;
};

// 修改为函数声明形式
function RenderInput({ flowInputList, nodeId, CustomComponent, mb = 5 }: Props) {
  const copyInputs = useMemo(
    () =>
      JSON.stringify(
        flowInputList.filter((input) => {
          if (input.isPro && true) return false;
          return true;
        }),
      ),
    [flowInputList],
  );
  const filterInputs = useMemo(() => {
    return JSON.parse(copyInputs) as FlowNodeInputItemType[];
  }, [copyInputs]);

  const memoCustomComponent = useMemo(() => CustomComponent || {}, [CustomComponent]);

  const Render = useMemo(() => {
    return filterInputs.map((input, index) => {
      const renderType = input.renderTypeList?.[input.selectedTypeIndex || 0];
      const isDynamic = !!input.canEdit;

      const RenderComponent = (() => {
        if (renderType === FlowNodeInputTypeEnum.custom && memoCustomComponent[input.key]) {
          return <>{memoCustomComponent[input.key]({ ...input })}</>;
        }

        const Component = RenderList.find((item) => item.types.includes(renderType))?.Component;

        if (!Component) return null;
        return <Component inputs={filterInputs} item={input} nodeId={nodeId} />;
      })();

      return renderType !== FlowNodeInputTypeEnum.hidden && !isDynamic ? (
        <div key={input.key} className={`relative ${index === 0 ? '' : 'my-2'}`}>
          {!!input.label && !hideLabelTypeList.includes(renderType) && (
            <InputLabel nodeId={nodeId} input={input} />
          )}
          {!!RenderComponent && (
            <div className="nodrag mt-2 w-full select-none">{RenderComponent}</div>
          )}
        </div>
      ) : null;
    });
  }, [filterInputs, memoCustomComponent, nodeId]);

  return <div className="rounded-2xl px-3 py-2">{Render}</div>;
}

export default React.memo(RenderInput);
